package org.hentai.bt.entity;

import org.hentai.bt.result.ResultList;
import org.hentai.bt.util.sql.SqlConnection;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public abstract class EntityModel {

    public void insert() throws IllegalAccessException, SQLException, ClassNotFoundException {
        Class<? extends EntityModel> aClass = getClass();
        String tableName = aClass.getSimpleName();
        Field[] declaredFields = aClass.getDeclaredFields();

        List<String> fieldNames = new ArrayList<>();
        List<Object> fieldValues = new ArrayList<>();

        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            if (declaredField.get(this) == null) {
                continue;
            }

            fieldNames.add(declaredField.getName());
            fieldValues.add(declaredField.get(this));
        }

        if (fieldNames.size() == 0 || fieldValues.size() == 0 || fieldNames.size() != fieldValues.size()) {
            return;
        }

        StringBuffer sql = new StringBuffer("INSERT INTO " + tableName + "(");

        int size = fieldNames.size();
        for (int i = 0; i < size; i++) {
            sql.append(fieldNames.get(i));
            if (i < size - 1) {
                sql.append(", ");
            }
        }

        sql.append(") VALUES (");
        for (int i = 0; i < size; i++) {
            sql.append("?");
            if (i < size - 1) {
                sql.append(", ");
            }
        }
        sql.append(");");

        System.out.println(sql);

        Connection conn = SqlConnection.getConn();
        PreparedStatement ps = conn.prepareStatement(sql.toString());
        for (int i = 0; i < size; i++) {
            String type = fieldValues.get(i).getClass().getSimpleName();
            switch (type) {
                case "Integer":
                    ps.setInt(i + 1, (Integer) fieldValues.get(i));
                    break;
                case "Long":
                    ps.setLong(i + 1, (Long) fieldValues.get(i));
                    break;
                case "Short":
                    ps.setShort(i + 1, (Short) fieldValues.get(i));
                    break;
                case "Byte":
                    ps.setByte(i + 1, (Byte) fieldValues.get(i));
                    break;
                case "Float":
                    ps.setFloat(i + 1, (Float) fieldValues.get(i));
                    break;
                case "Double":
                    ps.setDouble(i + 1, (Double) fieldValues.get(i));
                    break;
                case "String":
                    ps.setString(i + 1, (String) fieldValues.get(i));
                    break;
                case "Boolean":
                    ps.setBoolean(i + 1, (Boolean) fieldValues.get(i));
                    break;
                default:
                    ps.setObject(i + 1, fieldValues.get(i));
            }

        }
        System.out.println(ps);
        boolean b = ps.execute();

    }

    public void delete() {}

    public ResultList<? extends EntityModel> select() throws SQLException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        ResultList<? extends EntityModel> resultList = ResultList.getTable(this);
        return resultList;
    }

    public void update() {}

}
